import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';

function coerceFallback<T, S>(coerceFn: (v: any) => S, propName: string): (target: T, inputName: string) => any {
  return (target: T, inputName: string): any => {
    const _propName = propName || `_LV_${inputName.toUpperCase()}`;
    if (target[_propName]) {
      throw new Error(`${_propName} has exist.`);
    }
    Object.defineProperty(target, _propName, {
      configurable: true,
      enumerable: true,
      writable: true,
    });
    Object.defineProperty(target, inputName, {
      get() {
        return this[_propName];
      },
      set(value: any) {
        this[_propName] = coerceFn(value);
      },
    });
  };
}

export function InputBoolean<T>(propName?: string): (target: any, inputName: string) => void {
  // https://github.com/angular/components/pull/9283  0被认为true
  return coerceFallback(coerceBooleanProperty, propName);
}
export function InputNumber<T>(propName?: string): <D>(target: any, inputName: string) => void {
  return coerceFallback(coerceNumberProperty, propName);
}
